package com.example.mainserver.config;

import com.example.common.model.MailConstants;
import com.example.mainserver.mapper.MailSendLogMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class RabbitMqConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {

    private static final Logger logger = LoggerFactory.getLogger(RabbitMqConfig.class);

    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    MailSendLogMapper mailSendLogMapper;

    @PostConstruct
    public void initRabbitTemplate(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    @Bean
    Queue queue(){
        return new Queue(MailConstants.MAIL_QUEUE_NAME);
    }

    @Bean
    DirectExchange directExchange(){
        return new DirectExchange(MailConstants.MAIL_EXCHANGE_NAME);
    }

    @Bean
    Binding binding(){
        return BindingBuilder.bind(queue()).to(directExchange()).with(MailConstants.MAIL_ROUTING_KEY_NAME);
    }


    /**
     * 在 confirm 回调方法中，如果收到消息发送成功的回调，就将该条消息的 status 设置为1
     * （在消息发送时为消息设置 msgId，在消息发送成功回调时，通过 msgId 来唯一锁定该条消息）。
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        String msgId = correlationData.getId();
        if (ack){
            mailSendLogMapper.updateStatusByMsgId(msgId,MailConstants.SUCCESS);
            logger.info(msgId + " 消息发送成功");
        }else {
            logger.info(msgId + " 消息发送失败");
        }
    }

    @Override
    public void returnedMessage(ReturnedMessage returned) {
        logger.info("消息发送失败");
    }
}
